/* **********************************************************************************
 *
 * Copyright (c) Ascend.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for Ascend. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for Ascend, please send an email to ascend_adm@hotmail.com.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for Ascend.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Globalization;
using System.Drawing;
using Ascend.Resources;

namespace Ascend.Windows.Forms
{
    /// <summary>
    /// Provides a type converter to convert expandable objects to and from various other representations.
    /// </summary>
    public class GradientTabTabConverter : ExpandableObjectConverter
    {
            /// <summary>
        /// Initializes a new instance of the GradientTabTabConverter class.
        /// </summary>
        public GradientTabTabConverter()
        {            
        }

        /// <summary>
        /// Returns whether this converter can convert the object to the specified type.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that provides a format context.</param>
        /// <param name="destinationType">A <see cref="T:System.Type"></see> that represents the type you want to convert to.</param>
        /// <returns>true if this converter can perform the conversion; otherwise, false.</returns>
        public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType)
        {
            if (destinationType == typeof(GradientTabTabProperty)) return true;

            return base.CanConvertTo(context, destinationType);

        }

        /// <summary>
        /// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that provides a format context.</param>
        /// <param name="sourceType">A <see cref="T:System.Type"></see> that represents the type you want to convert from.</param>
        /// <returns>true if this converter can perform the conversion; otherwise, false.</returns>
        public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Type sourceType)
        {
            if (sourceType == typeof(string)) return true;

            return base.CanConvertFrom(context, sourceType);
   
        }

        /// <summary>
        /// Converts the given value object to the specified type, using the specified context and culture information.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that provides a format context.</param>
        /// <param name="culture">A <see cref="T:System.Globalization.CultureInfo"></see>. If null is passed, the current culture is assumed.</param>
        /// <param name="value">The <see cref="T:System.Object"></see> to convert.</param>
        /// <param name="destinationType">The <see cref="T:System.Type"></see> to convert the value parameter to.</param>
        /// <returns>An <see cref="T:System.Object"></see> that represents the converted value.</returns>
        public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType)
        {
            if (destinationType == null)
            {
                throw new ArgumentNullException("destinationType");

            }

            if (culture == null)
            {
                culture = CultureInfo.CurrentCulture;

            }

            if ((destinationType != typeof(System.String)) || !(value is GradientTabTabProperty))
            {
                return base.ConvertTo(context, culture, value, destinationType);

            }

            GradientTabTabProperty gradientTabTabProperty = (GradientTabTabProperty)value;

            char separator = culture.TextInfo.ListSeparator[0];

            StringBuilder displayText = new StringBuilder();

            displayText.Append(gradientTabTabProperty.Height.ToString(CultureInfo.CurrentCulture));
            displayText.Append(separator);
            displayText.Append(" ");

            displayText.Append(gradientTabTabProperty.GradientHighColor.ToString());
            displayText.Append(separator);
            displayText.Append(" ");

            displayText.Append(gradientTabTabProperty.GradientLowColor.ToString());
            displayText.Append(separator);
            displayText.Append(" ");

            displayText.Append(gradientTabTabProperty.BorderColor.ToString());
            displayText.Append(separator);
            displayText.Append(" ");

            displayText.Append(gradientTabTabProperty.HighlightGradientHighColor.ToString());
            displayText.Append(separator);
            displayText.Append(" ");

            displayText.Append(gradientTabTabProperty.HighlightGradientLowColor.ToString());
            displayText.Append(separator);
            displayText.Append(" ");

            displayText.Append(gradientTabTabProperty.ActiveGradientHighColor.ToString());
            displayText.Append(separator);
            displayText.Append(" ");

            displayText.Append(gradientTabTabProperty.ActiveGradientLowColor.ToString());
            displayText.Append(separator);
            displayText.Append(" ");

            displayText.Append(gradientTabTabProperty.ForeColor.ToString());

            return displayText.ToString();

        }

        /// <summary>
        /// Converts the given object to the type of this converter, using the specified context and culture information.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that provides a format context.</param>
        /// <param name="culture">The <see cref="T:System.Globalization.CultureInfo"></see> to use as the current culture.</param>
        /// <param name="value">The <see cref="T:System.Object"></see> to convert.</param>
        /// <returns>An <see cref="T:System.Object"></see> that represents the converted value.</returns>
        public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            string valueString = value as string;
            if (valueString == null)
            {
                return base.ConvertFrom(context, culture, value);

            }

            if (context == null)
            {
                return base.ConvertFrom(context, culture, value);

            }

            valueString = valueString.Trim();
            if (valueString.Length == 0)
            {
                return null;

            }

            if (culture == null)
            {
                culture = CultureInfo.CurrentCulture;

            }

            char separator = culture.TextInfo.ListSeparator[0];
            char[] separatorArray = new char[1] { separator };
            string[] textArray = valueString.Split(separatorArray);
            string[] textColorArray = new string[8];

            int height = int.Parse(textArray[0].Trim(), CultureInfo.CurrentCulture);
            int width = int.Parse(textArray[1].Trim(), CultureInfo.CurrentCulture);
            int colorCount = 0;

            for (int i = 2; i < textArray.Length; i++)
            {
                if (textArray[i].Contains("[") && textArray[i].Contains("]"))
                {
                    textColorArray[colorCount] = textArray[i].Substring((textArray[i].LastIndexOf('[') + 1), (textArray[i].LastIndexOf(']') - (textArray[i].LastIndexOf('[') + 1)));
                    colorCount++;

                }
                else
                {
                    if (textArray[i].Contains("["))
                    {
                        textColorArray[colorCount] = textArray[i].Substring((textArray[i].LastIndexOf('[') + 1)) + separator;

                    }
                    else if (textArray[i].Contains("]"))
                    {
                        textColorArray[colorCount] += textArray[i].Substring(0, textArray[i].LastIndexOf(']'));
                        colorCount++;

                    }
                    else
                    {
                        textColorArray[colorCount] += textArray[i] + separator;

                    }

                }

            }

            Color[] colorArray = new Color[textColorArray.Length];

            TypeConverter converter = TypeDescriptor.GetConverter(typeof(Color));
            for (int x = 0; x < colorArray.Length; x++)
            {
                if (textColorArray[x].Contains(separator.ToString()))
                {
                    string[] rgbArray = textColorArray[x].Split(separatorArray);
                    if (rgbArray.Length == 4)
                    {
                        int alpha = int.Parse(rgbArray[0].Trim().Substring(2), CultureInfo.CurrentCulture);
                        int red = int.Parse(rgbArray[1].Trim().Substring(2), CultureInfo.CurrentCulture);
                        int greeen = int.Parse(rgbArray[2].Trim().Substring(2), CultureInfo.CurrentCulture);
                        int blue = int.Parse(rgbArray[3].Trim().Substring(2), CultureInfo.CurrentCulture);

                        colorArray[x] = Color.FromArgb(alpha, red, greeen, blue);

                    }
                    else
                    {
                        throw new ArgumentException(ResourceText.GetLocalizedString("FailedParseFormatError"));

                    }

                }
                else
                {
                    colorArray[x] = (Color)converter.ConvertFromString(context, culture, textColorArray[x]);

                }

            }

            if (colorArray.Length == 8)
            {
                return new GradientTabTabProperty((GradientTab)context.Instance, height, width, colorArray[0], colorArray[1], colorArray[2], colorArray[3], colorArray[4], colorArray[5], colorArray[6], colorArray[7], ((GradientTab)context.Instance).TabTextAlign);

            }

            throw new ArgumentException(ResourceText.GetLocalizedString("FailedParseFormatError"));

        }

        /// <summary>
        /// Creates an instance of the Type that this TypeConverter is associated with, using the specified context, given a set of property values for the object.
        /// </summary>
        /// <param name="context">An ITypeDescriptorContext that provides a format context.</param>
        /// <param name="propertyValues">An System.Collections.IDictionary of new property values.</param>
        /// <returns>An System.Object representing the given System.Collections.IDictionary, or null if the object cannot be created. This method always returns null.</returns>
        public override System.Object CreateInstance(System.ComponentModel.ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");

            }

            if (propertyValues == null)
            {
                throw new ArgumentNullException("propertyValues");

            }

            GradientTabTabProperty gradientTabTabProperty = (GradientTabTabProperty)context.PropertyDescriptor.GetValue(context.Instance);

            return new GradientTabTabProperty((GradientTab)context.Instance, (int)propertyValues["Height"], (int)propertyValues["Width"], (Color)propertyValues["GradientHighColor"], (Color)propertyValues["GradientLowColor"], (Color)propertyValues["BorderColor"], (Color)propertyValues["HighlightGradientHighColor"], (Color)propertyValues["HighlightGradientLowColor"], (Color)propertyValues["ActiveGradientHighColor"], (Color)propertyValues["ActiveGradientLowColor"], (Color)propertyValues["ForeColor"], ((GradientTab)context.Instance).TabTextAlign);

        }

        /// <param name="context">An System.ComponentModel.ITypeDescriptorContext that provides a format context.</param>
        /// <returns>true if changing a property on this object requires a call to System.ComponentModel.TypeConverter.CreateInstance(System.Collections.IDictionary) to create a new value; otherwise, false.</returns>
        public override System.Boolean GetCreateInstanceSupported(System.ComponentModel.ITypeDescriptorContext context)
        {
            return false;

        }

        /// <summary>
        /// Retrieves the set of properties for this type. By default, a type does not have any properties to return. An easy implementation of this method can call the TypeDescriptor.GetProperties method for the correct data type. 
        /// </summary>
        /// <param name="context">An System.ComponentModel.ITypeDescriptorContext that provides a format context.</param>
        /// <param name="value">The value of the object to get the properties for.</param>
        /// <param name="attributes">An array of MemberAttribute objects that describe the properties.</param>
        /// <returns>A System.ComponentModel.PropertyDescriptorCollection with the properties that are exposed for this data type, or null if there are no properties.</returns>
        public override System.ComponentModel.PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, System.Object value, System.Attribute[] attributes)
        {
            PropertyDescriptorCollection propertyDescriptorCollection = TypeDescriptor.GetProperties(typeof(GradientTabTabProperty), attributes);
            string[] textArray = new string[9] { "Height", "GradientHighColor", "GradientLowColor", "BorderColor", "HighlightGradientHighColor", "HighlightGradientLowColor", "ActiveGradientHighColor", "ActiveGradientLowColor", "ForeColor" };
            return propertyDescriptorCollection.Sort(textArray);

        }

        /// <param name="context">An System.ComponentModel.ITypeDescriptorContext that provides a format context.</param>
        /// <returns>true if System.ComponentModel.TypeConverter.GetProperties(System.Object) should be called to find the properties of this object; otherwise, false.</returns>
        public override System.Boolean GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context)
        {
            return true;

        }

    }

}
